#include "chainsaw.h"
#include <filesystem>
#include "MakeManager.h"

namespace fs = std::filesystem;

void list_directory_recursive(fs::path const &dirPath, std::vector<fs::path> &dirs, int indent = 0);

void check_file_extension(std::vector<fs::path> &dirs, std::vector<std::string> const &check_extensions);

std::vector<std::string> read_data(std::string const &file_name);

int main(int argc, char **argv)
{
    PR(HI);

    cns::command cmd_tool(argc, argv);
    cmd_tool.print();

    std::vector<std::string> files = cmd_tool.get_option_arguments("f");

    if (files.size() != 2)
    {
        cns::error("usage: ", argv[0], " -f <dir1> <dir2>");
        return 0;
    }

    std::string dir1 = files[0];
    std::string dir2 = files[1];

    int n1 = static_cast<int>(dir1.size());
    int n2 = static_cast<int>(dir2.size());

    std::vector<fs::path> dirs;
    list_directory_recursive(dir1, dirs);

    std::vector<std::string>paths;
    for(auto t : dirs) paths.push_back(t.string());

    //check_file_extension(dirs, {".txt", ".proto", ".cpp"});
    PRP2(paths, "check dir");

    MakeManager mgr(dir2);
    mgr.init();

    for (auto t : dirs)
    {
        //PRP2(t.stem().string(), "file-name");
        //PRP2(t.extension().string(), "file-extension");
        mgr.write_method(t.stem().string(), t.extension().string(), read_data(t.string()));
    }

    mgr.write_main();
    mgr.write_CMakeLists_txt();

    PR(IH);
    return 0;
}

// todo 
// 获取一个路径下的所有文件
void list_directory_recursive(fs::path const &dirPath, std::vector<fs::path> &dirs, int indent)
{
    if (!fs::exists(dirPath))
    {
        cns::error(std::string(indent, ' '), "Path does not exist: ", dirPath);
        // std::cerr << std::string(indent, ' ') << "Path does not exist: " << dirPath << std::endl;
        return;
    }
    if (!fs::is_directory(dirPath))
    {
        cns::error(std::string(indent, ' '), "Not a directory: ", dirPath);
        return;
    }

    for (const auto &entry : fs::directory_iterator(dirPath))
    {
        const auto &path = entry.path();
        std::string prefix(indent, ' ');
        if (fs::is_directory(entry.status()))
        {
            list_directory_recursive(path, dirs, indent + 4);
            //cns::info(prefix, "[Dir ] ", path.filename().string());
        }
        else if (fs::is_regular_file(entry.status()))
        {
            dirs.push_back(path);
            //cns::info(prefix, "[File]      ", path.filename().string());
        }
        else
        {
            dirs.push_back(path);
            //cns::info(prefix, "[Other]     ", path.filename().string());
        }
    }
}

void check_file_extension(std::vector<fs::path> &dirs, std::vector<std::string> const &check_extensions)
{
    for (auto i = dirs.begin(); i != dirs.end();)
    {
        auto ext = i->extension();
        bool erase_flag = true;

        if (!ext.empty())
        {
            for (auto t : check_extensions)
            {
                if (t == ext)
                {
                    erase_flag = false;
                    break;
                }
            }
        }

        if (erase_flag)
        {
            i = dirs.erase(i);
        }
        else
        {
            ++i;
        }
    }
}

std::vector<std::string> read_data(std::string const &file_name)
{
    std::fstream file_read(file_name, std::ios::in);
    std::vector<std::string> data;

    std::string str;
    while (std::getline(file_read, str))
    {
        std::string result;

        for (auto c : str)
        {
            if (c == '\"')
            {
                result += '\\';
            }

            if (c == '\\')
            {
                result += '\\';
            }

            result += c;
        }

        data.push_back(result);
    }

    return data;
}
